package point;

/**
 * 题目：翻转字符串中的单词序列
 * 例子：my name is hsw => hsw is name my
 */
public class ReverseWords {
    public static void main(String[] args) {
        ReverseWords reverseWords = new ReverseWords();
        String res2 = reverseWords.reverseWords("my name is hsw");
        System.out.println(res2);
    }

    /**
     * 为节省空间，只用到字符串的char长度空间。
     * 双指针都从0开始，RP 递增，当遇到空格或者到达结尾时，说明 LP RP之间是一个单词，
     * 先把单词进行翻转，跳过空格翻转下一个单词，直到处理到结尾。
     * 最后把整个char[], 进行翻转，这样原本倒叙的单词翻转正确了。序列也按照要求进行了翻转。
     *
     * @param s
     * @return
     */
    public String reverseWords(String s) {
        if (s == null || s.isEmpty()) {
            return s;
        }
        char[] chars = s.toCharArray();
        int len = chars.length;
        int i = 0, j = 0;
        while (j <= len) {
            if (j == len || chars[j] == ' ') {
                // 翻转单词 char[]
                reverse(chars, i, j - 1);
                i = j + 1;
            }
            j++;
        }
        // 翻转整个 char[]
        reverse(chars, 0, len - 1);
        return new String(chars);
    }

    /**
     * 反转
     * @param chars
     * @param i
     * @param j
     */
    public void reverse(char[] chars, int i, int j) {
        while (i < j) {
            swap(chars, i, j);
            i++;
            j--;
        }
    }

    public void swap(char[] chars, int i, int j) {
        char temp = chars[i];
        chars[i] = chars[j];
        chars[j] = temp;
    }

    /**
     * 简单方案，根据空格把单词分成数组，数组翻转和空格再次拼接完成整体的翻转
     * 空间复杂度 为单词个数 N
     * @param s
     * @return
     */
    public String reverseWords2(String s) {
        if (s == null || s.isEmpty()) {
            return s;
        }
        String[] words = s.split(" ");
        StringBuilder reverseWords = new StringBuilder();
        for (int i = words.length - 1; i >= 0; i--) {
            reverseWords.append(words[i]);
            if (i != 0) {
                reverseWords.append(" ");
            }
        }
        return reverseWords.toString();

        // 基于Java 8 的简洁写法
//        List<String> words = new ArrayList<>(Arrays.stream(s.split(" ")).toList());
//        Collections.reverse(words);
//        return String.join(" ", words);
    }
}
